/**
 * 本地存储工具类
 * 解决无痕浏览器模式下数据共用问题
 * 通过为每个用户/会话创建独立的存储空间来实现数据隔离
 */

// 生成唯一的会话ID
const generateSessionId = (): string => {
  return 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
}

// 获取当前会话ID
const getCurrentSessionId = (): string => {
  let sessionId = sessionStorage.getItem('__app_session_id__')
  if (!sessionId) {
    sessionId = generateSessionId()
    sessionStorage.setItem('__app_session_id__', sessionId)
  }
  return sessionId
}

// 获取用户ID（如果已登录）
const getCurrentUserId = (): string | null => {
  try {
    // 优先从 localStorage 获取用户信息
    let userInfo = localStorage.getItem('userInfo')
    
    if (!userInfo) {
      // 如果 localStorage 中没有，则从基于会话ID的临时存储中获取
      const sessionId = getCurrentSessionId()
      userInfo = localStorage.getItem(`temp_${sessionId}_userInfo`) || sessionStorage.getItem(`${sessionId}_userInfo`)
    }
    
    if (userInfo) {
      const parsed = JSON.parse(userInfo)
      return parsed.id || parsed.userId || null
    }
  } catch (error) {
    console.warn('获取用户ID失败:', error)
  }
  return null
}

// 生成存储键名（优先使用用户ID，否则使用会话ID）
const generateStorageKey = (key: string): string => {
  const userId = getCurrentUserId()
  const sessionId = getCurrentSessionId()
  
  // 如果有用户ID，使用用户ID作为前缀（支持同一用户多个会话）
  if (userId) {
    return `user_${userId}_${key}`
  }
  
  // 否则使用会话ID作为前缀（支持未登录状态的数据隔离）
  return `${sessionId}_${key}`
}

/**
 * 隔离存储类
 * 为每个用户/会话提供独立的存储空间
 */
class IsolatedStorage {
  /**
   * 设置存储项
   * @param key 存储键
   * @param value 存储值
   * @param useSession 是否使用sessionStorage（默认false，使用localStorage）
   */
  setItem(key: string, value: string, useSession: boolean = false): void {
    try {
      const storageKey = generateStorageKey(key)
      const storage = useSession ? sessionStorage : localStorage
      storage.setItem(storageKey, value)
      
      // 记录存储操作（便于调试）
      console.log(`[Storage] 设置 ${useSession ? 'session' : 'local'} 存储:`, {
        原始键: key,
        实际键: storageKey,
        值长度: value.length
      })
    } catch (error) {
      console.error('设置存储失败:', error)
    }
  }

  /**
   * 获取存储项
   * @param key 存储键
   * @param useSession 是否使用sessionStorage（默认false，使用localStorage）
   * @returns 存储值或null
   */
  getItem(key: string, useSession: boolean = false): string | null {
    try {
      const storageKey = generateStorageKey(key)
      const storage = useSession ? sessionStorage : localStorage
      const value = storage.getItem(storageKey)
      
      console.log(`[Storage] 获取 ${useSession ? 'session' : 'local'} 存储:`, {
        原始键: key,
        实际键: storageKey,
        找到值: !!value
      })
      
      return value
    } catch (error) {
      console.error('获取存储失败:', error)
      return null
    }
  }

  /**
   * 移除存储项
   * @param key 存储键
   * @param useSession 是否使用sessionStorage（默认false，使用localStorage）
   */
  removeItem(key: string, useSession: boolean = false): void {
    try {
      const storageKey = generateStorageKey(key)
      const storage = useSession ? sessionStorage : localStorage
      storage.removeItem(storageKey)
      
      console.log(`[Storage] 移除 ${useSession ? 'session' : 'local'} 存储:`, {
        原始键: key,
        实际键: storageKey
      })
    } catch (error) {
      console.error('移除存储失败:', error)
    }
  }

  /**
   * 清除当前用户/会话的所有存储
   * @param useSession 是否清除sessionStorage（默认false，清除localStorage）
   */
  clearUserData(useSession: boolean = false): void {
    try {
      const userId = getCurrentUserId()
      const sessionId = getCurrentSessionId()
      const storage = useSession ? sessionStorage : localStorage
      
      // 确定要清除的前缀
      const prefixes = []
      if (userId) {
        prefixes.push(`user_${userId}_`)
      }
      prefixes.push(`${sessionId}_`)
      
      // 如果是localStorage，还要清除临时用户信息
      if (!useSession) {
        prefixes.push(`temp_${sessionId}_`)
      }
      
      // 获取所有键并过滤出需要清除的键
      const keysToRemove: string[] = []
      for (let i = 0; i < storage.length; i++) {
        const key = storage.key(i)
        if (key && prefixes.some(prefix => key.startsWith(prefix))) {
          keysToRemove.push(key)
        }
      }
      
      // 移除匹配的键
      keysToRemove.forEach(key => storage.removeItem(key))
      
      console.log(`[Storage] 清除用户数据完成:`, {
        存储类型: useSession ? 'sessionStorage' : 'localStorage',
        前缀列表: prefixes,
        清除数量: keysToRemove.length,
        清除的键: keysToRemove
      })
    } catch (error) {
      console.error('清除用户数据失败:', error)
    }
  }

  /**
   * 获取当前会话ID（用于调试）
   */
  getSessionId(): string {
    return getCurrentSessionId()
  }

  /**
   * 获取当前用户ID（用于调试）
   */
  getUserId(): string | null {
    return getCurrentUserId()
  }

  /**
   * 设置用户信息（登录后调用）
   * @param userInfo 用户信息对象
   */
  setUserInfo(userInfo: any): void {
    try {
      // 直接保存到 localStorage
      localStorage.setItem('userInfo', JSON.stringify(userInfo))
      
      // 获取当前会话ID
      const sessionId = getCurrentSessionId()
      
      // 保存到基于会话ID的临时位置，确保不同窗口隔离
      localStorage.setItem(`temp_${sessionId}_userInfo`, JSON.stringify(userInfo))
      
      // 同时保存到会话存储作为备份
      sessionStorage.setItem(`${sessionId}_userInfo`, JSON.stringify(userInfo))
      
      console.log('[Storage] 用户信息已设置，存储空间已切换到用户模式:', {
        用户ID: userInfo.id || userInfo.userId,
        会话ID: sessionId,
        临时键: `temp_${sessionId}_userInfo`
      })
    } catch (error) {
      console.error('设置用户信息失败:', error)
    }
  }

  /**
   * 获取用户信息
   * @returns 用户信息对象或null
   */
  getUserInfo(): any {
    try {
      // 优先从 localStorage 获取用户信息
      let userInfoStr = localStorage.getItem('userInfo')
      
      if (!userInfoStr) {
        // 如果 localStorage 中没有，则从基于会话ID的临时存储中获取
        const sessionId = getCurrentSessionId()
        userInfoStr = localStorage.getItem(`temp_${sessionId}_userInfo`) || sessionStorage.getItem(`${sessionId}_userInfo`)
      }
      
      if (userInfoStr) {
        return JSON.parse(userInfoStr)
      }
    } catch (error) {
      console.error('获取用户信息失败:', error)
    }
    return null
  }

  /**
   * 用户登出时清理数据
   */
  logout(): void {
    // 获取当前会话ID
    const sessionId = getCurrentSessionId()
    
    // 清除基于会话ID的临时用户信息
    localStorage.removeItem(`temp_${sessionId}_userInfo`)
    sessionStorage.removeItem(`${sessionId}_userInfo`)
    
    // 清除localStorage中的用户数据
    this.clearUserData(false)
    
    // 清除sessionStorage中的用户数据
    this.clearUserData(true)
    
    // 重新生成会话ID
    sessionStorage.removeItem('__app_session_id__')
    
    console.log('[Storage] 用户登出，所有数据已清理:', {
      清除的会话ID: sessionId,
      清除的临时键: [`temp_${sessionId}_userInfo`, `${sessionId}_userInfo`]
    })
  }

  /**
   * 清理所有数据（用于完全重置）
   */
  clearAll(): void {
    try {
      const userId = getCurrentUserId()
      const sessionId = getCurrentSessionId()
      
      // 清理localStorage中的所有相关数据
      const localKeys: string[] = []
      for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i)
        if (key && (key.startsWith(`user_${userId}_`) || key.startsWith(`${sessionId}_`))) {
          localKeys.push(key)
        }
      }
      localKeys.forEach(key => localStorage.removeItem(key))
      
      // 清理sessionStorage中的所有相关数据
      const sessionKeys: string[] = []
      for (let i = 0; i < sessionStorage.length; i++) {
        const key = sessionStorage.key(i)
        if (key && (key.startsWith(`user_${userId}_`) || key.startsWith(`${sessionId}_`) || key === '__app_session_id__')) {
          sessionKeys.push(key)
        }
      }
      sessionKeys.forEach(key => sessionStorage.removeItem(key))
      
      console.log('[Storage] 所有数据已清理完成:', {
        localStorage清理数量: localKeys.length,
        sessionStorage清理数量: sessionKeys.length
      })
    } catch (error) {
      console.error('清理所有数据失败:', error)
    }
  }
}

// 创建单例实例
const isolatedStorage = new IsolatedStorage()

// 导出实例和工具函数
export default isolatedStorage
export { IsolatedStorage, getCurrentSessionId, getCurrentUserId }

// 兼容性方法（逐步替换原有的localStorage调用）
export const storage = {
  setItem: (key: string, value: string) => isolatedStorage.setItem(key, value),
  getItem: (key: string) => isolatedStorage.getItem(key),
  removeItem: (key: string) => isolatedStorage.removeItem(key),
  clear: () => isolatedStorage.clearUserData(),
  setUserInfo: (userInfo: any) => isolatedStorage.setUserInfo(userInfo),
  getUserInfo: () => isolatedStorage.getUserInfo(),
  logout: () => isolatedStorage.logout()
}